package megrez.bussiness.system.web.rest;

import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import megrez.bussiness.system.entity.Dict;
import megrez.bussiness.system.entity.DictDetail;
import megrez.bussiness.system.repository.DictDetailRepository;
import megrez.bussiness.system.repository.DictRepository;
import megrez.bussiness.system.service.DictService;
import megrez.bussiness.system.web.dto.DictDetailDto;
import megrez.bussiness.system.web.dto.DictDto;
import megrez.bussiness.system.web.dto.DictFlatDto;
import megrez.bussiness.system.web.mapper.DictDetailMapper;
import megrez.bussiness.system.web.mapper.DictMapper;

/**
 * 字典接口
 * 
 * @author Lucky Yang
 * @since 0.0.1
 */
@RestController
@RequestMapping("/v1/dicts")
@RequiredArgsConstructor
public class DictResource {
    private final DictDetailRepository dictDetailRepository;
    private final DictRepository dictRepository;

    private final DictService dictService;

    /**
     * 创建字典
     * 
     * @return
     */
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public String createDict(@RequestBody DictDto dictDto) {
        Dict entity = dictRepository.save(DictMapper.INST.toEntity(dictDto));
        return entity.getId().toString();
    }

    /**
     * 创建字典
     * 
     * @return
     */
    @PostMapping("/{dictId}/details")
    @ResponseStatus(HttpStatus.CREATED)
    public String createDictDetail(@PathVariable("dictId") Long dictId, @RequestBody DictDetailDto dictDetailDto) {
        DictDetail entity = dictService.saveDictDetail(dictId, DictDetailMapper.INST.toEntity(dictDetailDto));
        return entity.getId().toString();
    }

    /**
     * 更新字典
     * 
     * @return
     */
    @PutMapping("/{dictId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void updateDict(@PathVariable("dictId") Long dictId, @RequestBody DictDto dictDto) {
        dictService.updateDict(dictId, DictMapper.INST.toEntity(dictDto));
    }

    /**
     * 更新字典明细
     * 
     * @return
     */
    @PutMapping("/details/{dictDetailId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void updateDictDetail(@PathVariable("dictDetailId") Long dictDetailId,
            @RequestBody DictDetailDto dictDetailDto) {
        dictService.updateDictDetail(dictDetailId, DictDetailMapper.INST.toEntity(dictDetailDto));
    }

    /**
     * 删除字典
     * 
     * @return
     */
    @DeleteMapping("/{dictId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteDict(@PathVariable("dictId") Long dictId) {
        dictService.deleteDictById(dictId);
    }

    /**
     * 删除字典
     * 
     * @return
     */
    @DeleteMapping("/details/{dictDetailId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteDictDetail(@PathVariable("dictDetailId") Long dictDetailId) {
        dictDetailRepository.deleteById(dictDetailId);
    }

    @GetMapping("/{dictId}")
    public DictDto getByDictId(@PathVariable("dictId") Long dictId) {
        Dict entity = dictService.findByDictId(dictId);
        return DictMapper.INST.toDto(entity);
    }

    @GetMapping("/details/{dictDetailId}")
    public DictDetailDto getByDictDetailId(@PathVariable("dictDetailId") Long dictDetailId) {
        DictDetail entity = dictService.findByDictDetailId(dictDetailId);
        return DictDetailMapper.INST.toDto(entity);
    }

    @GetMapping("/{dictId}/detials")
    public List<DictDetailDto> getDetailByDictId(@PathVariable("dictId") Long dictId) {
        Dict dict = dictService.findByDictId(dictId);

        List<DictDetail> entities = dictDetailRepository.findByDict(dict);
        entities.sort(Comparator.comparing(DictDetail::getOrderNo).thenComparing(DictDetail::getCode));
        return DictDetailMapper.INST.toDto(entities);
    }

    @GetMapping("/details")
    public List<DictFlatDto> getDictAndDetails(
            @RequestParam(value = "codes", required = false) Set<String> codes) {
        return dictRepository.findDetailsByCodeIn(codes)
                .stream()
                .sorted(Comparator.comparing(Dict::getCode))
                .map(DictFlatDto::of)
                .collect(Collectors.toList());

    }

}
